use auth::{get_users, save_users, LoginRole, User};
use clap::{Parser, Subcommand};

#[derive(Parser)]
#[command()]
struct Args {
    #[command(subcommand)]
    command: Option<Commands>
}

#[derive(Subcommand)]
enum Commands {
    // list all users
    List,
    Add {
        username: String,
        password: String,
        #[arg(long)]
        admin: Option<bool>
    },
    Delete {
        username: String,
    },
    Changepasswd {
        username: String,
        password: String,
    }
}

fn list_users() {
    println!("{:<20}{:<20}", "Username", "Password");
    println!("{:-<40}", "");
    let users = auth::get_users();

    users
        .iter()
        .for_each(|(_, user)| {
            println!("{:<20}{:<20}", user.username, user.password);
        })
}

fn add_user(username: String, password: String, admin: bool) {

    let mut users = get_users();
    let role = if admin {
        LoginRole::Admin
    } else {
        LoginRole::User
    };
    let user = User::new(&username, &password, role);
    users.insert(username, user);
    save_users(users);


}

fn delete_user(username: String) {
    let mut users = get_users();
    if users.contains_key(&username) {
        users.remove(&username);
        save_users(users);
    } else {
        println!("User {username} not found");
    }

}

fn change_password(username: String, password: String) {
    let mut users = get_users();
    if let Some(user) = users.get_mut(&username){
        user.password = auth::hash_password(&password);
        save_users(users);
    } else {
        println!("User {username} not found");
    }
}

fn main() {
    let cli = Args::parse();
    match cli.command {
        Some(Commands::List) => {
            // list all users
            list_users()
        },
        Some(Commands::Add { username, password, admin }) => {
            let admin = admin.unwrap_or(false);
            add_user(username, password, admin);
        },
        Some(Commands::Delete { username }) => {
            delete_user(username)
        },
        Some(Commands::Changepasswd { username, password }) => {
            change_password(username, password)
        },
        None => {
            // do nothing
            println!("Run with --help");
        }
    }

}
